home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1999 #2 / Amiga Plus CD - 1999 - No. 2.iso / System-Boost / Workbench / ToolManager / Source / Prefs / dock.c < prev    next >
C/C++ Source or Header  |  1998-06-17  |  27KB  |  814 lines

  1. /*
  2.  * dock.c  V3.1
  3.  *
  4.  * TM Dock object class
  5.  *
  6.  * Copyright (C) 1990-98 Stefan Becker
  7.  *
  8.  * This source code is for educational purposes only. You may study it
  9.  * and copy ideas or algorithms from it for your own projects. It is
  10.  * not allowed to use any of the source codes (in full or in parts)
  11.  * in other programs. Especially it is not allowed to create variants
  12.  * of ToolManager or ToolManager-like programs from this source code.
  13.  *
  14.  */
  15.  
  16. #include "toolmanager.h"
  17.  
  18. /* Local data */
  19. #define PROPCHUNKS 5
  20. static const ULONG PropChunkTable[2 * PROPCHUNKS] = {
  21.  ID_TMDO, ID_DATA,
  22.  ID_TMDO, ID_FONT,
  23.  ID_TMDO, ID_HKEY,
  24.  ID_TMDO, ID_NAME,
  25.  ID_TMDO, ID_PSCR
  26. };
  27. static const char *TextTitle;
  28. static const char *HelpHotKey;
  29. static const char *HelpPublicScreen;
  30. static const char *HelpPosition;
  31. static const char *TextColumns;
  32. static const char *HelpColumns;
  33. static const char *TextFont;
  34. static const char *HelpFont;
  35. static const char *TextActivated;
  36. static const char *HelpActivated;
  37. static const char *TextBackdrop;
  38. static const char *HelpBackdrop;
  39. static const char *TextBorder;
  40. static const char *HelpBorder;
  41. static const char *TextCentered;
  42. static const char *HelpCentered;
  43. static const char *TextFrontmost;
  44. static const char *HelpFrontmost;
  45. static const char *TextImages;
  46. static const char *HelpImages;
  47. static const char *TextMenu;
  48. static const char *HelpMenu;
  49. static const char *TextPopup;
  50. static const char *HelpPopup;
  51. static const char *TextSticky;
  52. static const char *HelpSticky;
  53. static const char *TextText;
  54. static const char *HelpText;
  55. static const char *TextEntries;
  56. static const char *HelpEntries;
  57. static const char *TextSelectFont;
  58.  
  59. /* Dock class instance data */
  60. struct DockClassData {
  61.  ULONG           dcd_Flags;
  62.  ULONG           dcd_LeftEdge;
  63.  ULONG           dcd_TopEdge;
  64.  ULONG           dcd_Columns;
  65.  const char     *dcd_HotKey;
  66.  const char     *dcd_Font;
  67.  const char     *dcd_PubScreen;
  68.  struct MinList  dcd_Entries;
  69.  Object         *dcd_Active;
  70.  Object         *dcd_HotKeyString;
  71.  Object         *dcd_Position;
  72.  Object         *dcd_ColsNumeric;
  73.  Object         *dcd_PubScreenString;
  74.  Object         *dcd_FontString;
  75.  Object         *dcd_ListView;
  76.  Object         *dcd_EntryList;
  77.  Object         *dcd_Activated;
  78.  Object         *dcd_Backdrop;
  79.  Object         *dcd_Border;
  80.  Object         *dcd_Centered;
  81.  Object         *dcd_Frontmost;
  82.  Object         *dcd_Images;
  83.  Object         *dcd_Menu;
  84.  Object         *dcd_Popup;
  85.  Object         *dcd_Sticky;
  86.  Object         *dcd_Text;
  87. };
  88. #define TYPED_INST_DATA(cl, o) ((struct DockClassData *) INST_DATA((cl), (o)))
  89.  
  90. /* Dock class method: OM_NEW */
  91. #undef  DEBUGFUNCTION
  92. #define DEBUGFUNCTION DockClassNew
  93. static ULONG DockClassNew(Class *cl, Object *obj, struct opSet *ops)
  94. {
  95.  DOCK_LOG((LOG1(Tags, "0x%08lx", ops->ops_AttrList),
  96.            PrintTagList(ops->ops_AttrList)))
  97.  
  98.  /* Create object */
  99.  if (obj = (Object *) DoSuperNew(cl, obj,
  100.                                        MUIA_Window_Title, TextTitle,
  101.                                        MUIA_HelpNode,     "DockWindow",
  102.                                        TMA_Type,          TMOBJTYPE_DOCK,
  103.                                        TAG_MORE,          ops->ops_AttrList)) {
  104.   struct DockClassData *dcd = TYPED_INST_DATA(cl, obj);
  105.  
  106.   /* Initalize entries list */
  107.   NewList((struct List *) &dcd->dcd_Entries);
  108.  
  109.   /* Initialize instance data */
  110.   dcd->dcd_Flags       = DATA_DOCKF_ACTIVATED | DATA_DOCKF_IMAGES;
  111.   dcd->dcd_LeftEdge    = 0;
  112.   dcd->dcd_TopEdge     = 0;
  113.   dcd->dcd_Columns     = 1;
  114.   dcd->dcd_HotKey      = NULL;
  115.   dcd->dcd_Font        = NULL;
  116.   dcd->dcd_PubScreen   = NULL;
  117.   dcd->dcd_Active      = NULL;
  118.  }
  119.  
  120.  DOCK_LOG(LOG1(Result, "0x%08lx", obj))
  121.  
  122.  /* Return pointer to created object */
  123.  return((ULONG) obj);
  124. }
  125.  
  126. /* Dock class method: OM_DISPOSE */
  127. #undef  DEBUGFUNCTION
  128. #define DEBUGFUNCTION DockClassDispose
  129. static ULONG DockClassDispose(Class *cl, Object *obj, Msg msg)
  130. {
  131.  struct DockClassData *dcd = TYPED_INST_DATA(cl, obj);
  132.  
  133.  DOCK_LOG(LOG1(Disposing, "0x%08lx", obj))
  134.  
  135.  /* Free dock entries */
  136.  FreeDockEntries(&dcd->dcd_Entries);
  137.  
  138.  /* Free strings */
  139.  if (dcd->dcd_HotKey)    FreeVector(dcd->dcd_HotKey);
  140.  if (dcd->dcd_Font)      FreeVector(dcd->dcd_Font);
  141.  if (dcd->dcd_PubScreen) FreeVector(dcd->dcd_PubScreen);
  142.  
  143.  /* Call SuperClass */
  144.  return(DoSuperMethodA(cl, obj, msg));
  145. }
  146.  
  147. /* Dock class method: TMM_Finish */
  148. #undef  DEBUGFUNCTION
  149. #define DEBUGFUNCTION DockClassFinish
  150. static ULONG DockClassFinish(Class *cl, Object *obj, struct TMP_Finish *tmpf)
  151. {
  152.  struct DockClassData *dcd = TYPED_INST_DATA(cl, obj);
  153.  
  154.  DOCK_LOG(LOG1(Type, "%ld", tmpf->tmpf_Type))
  155.  
  156.  /* MUI objects allocated? */
  157.  if (dcd->dcd_Active) {
  158.  
  159.   /* Use or Cancel? */
  160.   if (tmpf->tmpf_Type == TMV_Finish_Use) {
  161.    int               i  = 0;
  162.    struct DockEntry *de;
  163.  
  164.    /* Free old entries */
  165.    FreeDockEntries(&dcd->dcd_Entries);
  166.  
  167.    /* For each entry in list */
  168.    do {
  169.     struct DockEntry *new;
  170.  
  171.     /* Get next entry */
  172.     DoMethod(dcd->dcd_EntryList, MUIM_List_GetEntry, i++, &de);
  173.  
  174.     DOCK_LOG(LOG1(Next entry, "0x%08lx", de))
  175.  
  176.     /* End of list reached? */
  177.     if (de) {
  178.  
  179.      /* No, copy entry. Leave loop if error */
  180.      if ((new = CopyDockEntry(de, obj)) == NULL) break;
  181.  
  182.      /* Append new entry to list */
  183.      AddTail((struct List *) &dcd->dcd_Entries, (struct Node *) new);
  184.     }
  185.    } while (de);
  186.  
  187.    /* Get new string contents */
  188.    dcd->dcd_HotKey    = GetStringContents(dcd->dcd_HotKeyString,
  189.                                           dcd->dcd_HotKey);
  190.    dcd->dcd_Font      = GetStringContents(dcd->dcd_FontString,
  191.                                           dcd->dcd_Font);
  192.    dcd->dcd_PubScreen = GetStringContents(dcd->dcd_PubScreenString,
  193.                                           dcd->dcd_PubScreen);
  194.  
  195.    /* Get new position values */
  196.    GetAttr(MUIA_Popposition_XPos, dcd->dcd_Position,  &dcd->dcd_LeftEdge);
  197.    GetAttr(MUIA_Popposition_YPos, dcd->dcd_Position,  &dcd->dcd_TopEdge);
  198.  
  199.    /* Get new columns count */
  200.    GetAttr(MUIA_Numeric_Value, dcd->dcd_ColsNumeric, &dcd->dcd_Columns);
  201.  
  202.    /* Get new flag status */
  203.    dcd->dcd_Flags = GetCheckmarkState(dcd->dcd_Activated,
  204.                                       DATA_DOCKF_ACTIVATED) |
  205.                     GetCheckmarkState(dcd->dcd_Backdrop,
  206.                                       DATA_DOCKF_BACKDROP)  |
  207.                     GetCheckmarkState(dcd->dcd_Border,
  208.                                       DATA_DOCKF_BORDER)    |
  209.                     GetCheckmarkState(dcd->dcd_Centered,
  210.                                       DATA_DOCKF_CENTERED)  |
  211.                     GetCheckmarkState(dcd->dcd_Frontmost,
  212.                                       DATA_DOCKF_FRONTMOST) |
  213.                     GetCheckmarkState(dcd->dcd_Images,
  214.                                       DATA_DOCKF_IMAGES)    |
  215.                     GetCheckmarkState(dcd->dcd_Menu,
  216.                                       DATA_DOCKF_MENU)      |
  217.                     GetCheckmarkState(dcd->dcd_Popup,
  218.                                       DATA_DOCKF_POPUP)     |
  219.                     GetCheckmarkState(dcd->dcd_Sticky,
  220.                                       DATA_DOCKF_STICKY)    |
  221.                     GetCheckmarkState(dcd->dcd_Text,
  222.                                       DATA_DOCKF_TEXT);
  223.   }
  224.  
  225.   /* Reset pointer to file name area */
  226.   dcd->dcd_Active = NULL;
  227.  }
  228.  
  229.  /* Call SuperClass */
  230.  return(DoSuperMethodA(cl, obj, (Msg) tmpf));
  231. }
  232.  
  233. /* Dock class method: TMM_Notify */
  234. #undef  DEBUGFUNCTION
  235. #define DEBUGFUNCTION DockClassNotify
  236. static ULONG DockClassNotify(Class *cl, Object *obj, struct TMP_Notify *tmpn)
  237. {
  238.  DOCK_LOG(LOG1(Type, "0x%08lx", tmpn->tmpn_Data->ad_Object))
  239.  
  240.  /* Object deleted? */
  241.  if (tmpn->tmpn_Data->ad_Object == NULL) {
  242.   struct DockEntry *de = (struct DockEntry *)
  243.                           GetHead(&TYPED_INST_DATA(cl, obj)->dcd_Entries);
  244.  
  245.   /* For each entry in the list */
  246.   while (de) {
  247.  
  248.    ENTRIES_LOG(LOG1(Next entry, "0x%08lx", de))
  249.  
  250.    /* Try to remove attached object. Leave loop if object found */
  251.    if (RemoveDockEntryAttach(de, tmpn->tmpn_Data)) break;
  252.  
  253.    de = (struct DockEntry *) GetSucc((struct MinNode *) de);
  254.   }
  255.  }
  256.  
  257.  /* Return 1 to indicate that the method is implemented */
  258.  return(1);
  259. }
  260.  
  261. /* Dock class method: TMM_Edit */
  262. #undef  DEBUGFUNCTION
  263. #define DEBUGFUNCTION DockClassEdit
  264. static ULONG DockClassEdit(Class *cl, Object *obj, struct TMP_Edit *tmpe)
  265. {
  266.  struct DockClassData *dcd = TYPED_INST_DATA(cl, obj);
  267.  Object               *delete;
  268.  
  269.  /* MUI objects allocated? */
  270.  if (dcd->dcd_Active) {
  271.  
  272.   DOCK_LOG(LOG0(Object already active))
  273.  
  274.   /* Yes, forward method to SuperClass */
  275.   DoSuperMethodA(cl, obj, (Msg) tmpe);
  276.  
  277.  /* No, create object edit area */
  278.  } else if (dcd->dcd_Active =
  279.     VGroup,
  280.      Child, ColGroup(2),
  281.       Child, Label2(TextGlobalHotKey),
  282.       Child, dcd->dcd_HotKeyString    = TMPopHotKey(dcd->dcd_HotKey,
  283.                                                     HelpHotKey),
  284.       End,
  285.       Child, Label2(TextGlobalPublicScreen),
  286.       Child, dcd->dcd_PubScreenString = TMPopScreen(dcd->dcd_PubScreen,
  287.                                                     HelpPublicScreen),
  288.       End,
  289.       Child, Label2(TextFont),
  290.       Child, dcd->dcd_FontString      = NewObject(PopASLClass->mcc_Class, NULL,
  291.        MUIA_Popasl_Type,      ASL_FontRequest,
  292.        MUIA_Popstring_String, TMString(dcd->dcd_Font, LENGTH_STRING, NULL),
  293.        MUIA_Popstring_Button, PopButton(MUII_PopUp),
  294.        MUIA_ShortHelp,        HelpFont,
  295.        ASLFR_TitleText,       TextSelectFont,
  296.       End,
  297.      End,
  298.      Child, HGroup,
  299.       Child, Label1(TextColumns),
  300.       Child, dcd->dcd_ColsNumeric = NumericbuttonObject,
  301.        MUIA_Numeric_Min,   1,
  302.        MUIA_Numeric_Max,   20,
  303.        MUIA_Numeric_Value, dcd->dcd_Columns,
  304.        MUIA_CycleChain,    TRUE,
  305.        MUIA_ShortHelp,     HelpColumns,
  306.       End,
  307.       Child, Label2(TextGlobalPosition),
  308.       Child, dcd->dcd_Position    = TMPopPosition(dcd->dcd_LeftEdge,
  309.                                                   dcd->dcd_TopEdge,
  310.                                                   HelpPosition),
  311.       End,
  312.      End,
  313.      Child, VGroup,
  314.       MUIA_Background, MUII_GroupBack,
  315.       MUIA_Frame,      MUIV_Frame_Group,
  316.       MUIA_FrameTitle, TextEntries,
  317.       MUIA_ShortHelp,  HelpEntries,
  318.       Child, dcd->dcd_ListView = ListviewObject,
  319.        MUIA_Listview_DragType, MUIV_Listview_DragType_Immediate,
  320.        MUIA_Listview_List,     dcd->dcd_EntryList =
  321.         NewObject(EntryListClass->mcc_Class, NULL,
  322.         TMA_Entries,     &dcd->dcd_Entries,
  323.         MUIA_Frame,      MUIV_Frame_InputList,
  324.        End,
  325.        MUIA_CycleChain,        TRUE,
  326.       End,
  327.       Child, delete = MakeButton(TextGlobalDelete, HelpGlobalDelete),
  328.      End,
  329.      Child, ColGroup(11),
  330.       Child, Label1(TextActivated),
  331.       Child, dcd->dcd_Activated =
  332.        MakeCheckmark(dcd->dcd_Flags & DATA_DOCKF_ACTIVATED, HelpActivated),
  333.       Child, HSpace(0),
  334.       Child, Label1(TextBackdrop),
  335.       Child, dcd->dcd_Backdrop =
  336.        MakeCheckmark(dcd->dcd_Flags & DATA_DOCKF_BACKDROP, HelpBackdrop),
  337.       Child, HSpace(0),
  338.       Child, Label1(TextBorder),
  339.       Child, dcd->dcd_Border =
  340.        MakeCheckmark(dcd->dcd_Flags & DATA_DOCKF_BORDER, HelpBorder),
  341.       Child, HSpace(0),
  342.       Child, Label1(TextMenu),
  343.       Child, dcd->dcd_Menu =
  344.        MakeCheckmark(dcd->dcd_Flags & DATA_DOCKF_MENU, HelpMenu),
  345.       Child, Label1(TextFrontmost),
  346.       Child, dcd->dcd_Frontmost =
  347.        MakeCheckmark(dcd->dcd_Flags & DATA_DOCKF_FRONTMOST, HelpFrontmost),
  348.       Child, HSpace(0),
  349.       Child, Label1(TextPopup),
  350.       Child, dcd->dcd_Popup =
  351.        MakeCheckmark(dcd->dcd_Flags & DATA_DOCKF_POPUP, HelpPopup),
  352.       Child, HSpace(0),
  353.       Child, Label1(TextCentered),
  354.       Child, dcd->dcd_Centered =
  355.        MakeCheckmark(dcd->dcd_Flags & DATA_DOCKF_CENTERED, HelpCentered),
  356.       Child, HSpace(0),
  357.       Child, Label1(TextSticky),
  358.       Child, dcd->dcd_Sticky =
  359.        MakeCheckmark(dcd->dcd_Flags & DATA_DOCKF_STICKY, HelpSticky),
  360.       Child, HSpace(0),
  361.       Child, HSpace(0),
  362.       Child, HSpace(0),
  363.       Child, Label1(TextImages),
  364.       Child, dcd->dcd_Images =
  365.        MakeCheckmark(dcd->dcd_Flags & DATA_DOCKF_IMAGES, HelpImages),
  366.       Child, HSpace(0),
  367.       Child, Label1(TextText),
  368.       Child, dcd->dcd_Text =
  369.        MakeCheckmark(dcd->dcd_Flags & DATA_DOCKF_TEXT, HelpText),
  370.      End,
  371.     End) {
  372.  
  373.   DOCK_LOG(LOG1(Dock Area, "0x%08lx", dcd->dcd_Active))
  374.  
  375.   /* Gadget actions */
  376.   DoMethod(delete,             MUIM_Notify, MUIA_Pressed,  FALSE,
  377.            dcd->dcd_EntryList, 2, MUIM_List_Remove, MUIV_List_Remove_Active);
  378.   DoMethod(dcd->dcd_Centered,  MUIM_Notify, MUIA_Selected, MUIV_EveryTime,
  379.            obj,                1, TMM_Change);
  380.   DoMethod(dcd->dcd_Frontmost, MUIM_Notify, MUIA_Selected, MUIV_EveryTime,
  381.            obj,                1, TMM_Change);
  382.   DoMethod(dcd->dcd_Text,      MUIM_Notify, MUIA_Selected, MUIV_EveryTime,
  383.            obj,                1, TMM_Change);
  384.  
  385.   /* List actions */
  386.   DoMethod(dcd->dcd_ListView,  MUIM_Notify, MUIA_Listview_DoubleClick, TRUE,
  387.            obj,                1, TMM_DoubleClicked, 0);
  388.  
  389.   /* Set initial disable states */
  390.   DoMethod(obj, TMM_Change);
  391.  
  392.   /* Forward method to SuperClass */
  393.   if (DoSuperMethod(cl, obj, TMM_Edit, dcd->dcd_Active)
  394.       == NULL) {
  395.  
  396.    /* SuperClass failed, delete file area again */
  397.    MUI_DisposeObject(dcd->dcd_Active);
  398.    dcd->dcd_Active = NULL;
  399.   }
  400.  }
  401.  
  402.  DOCK_LOG(LOG1(Result, "0x%08lx", dcd->dcd_Active))
  403.  
  404.  /* Return pointer to file area object to indicate success */
  405.  return((ULONG) dcd->dcd_Active);
  406. }
  407.  
  408. /* Dock class method: TMM_Change */
  409. #undef  DEBUGFUNCTION
  410. #define DEBUGFUNCTION DockClassChange
  411. static ULONG DockClassChange(Class *cl, Object *obj)
  412. {
  413.  struct DockClassData *dcd = TYPED_INST_DATA(cl, obj);
  414.  
  415.  DOCK_LOG(LOG0(Entry))
  416.  
  417.  /* Public screen gadget is disabled when "Frontmost" is selected */
  418.  SetDisabledState(dcd->dcd_PubScreenString,
  419.                   GetCheckmarkState(dcd->dcd_Frontmost, TRUE));
  420.  
  421.  /* Font gadget is disabled when "Text" is not selected */
  422.  SetDisabledState(dcd->dcd_FontString,
  423.                   !GetCheckmarkState(dcd->dcd_Text, TRUE));
  424.  
  425.  /* Position icons disabled when "Centered" is selected */
  426.  SetDisabledState(dcd->dcd_Position,
  427.                   GetCheckmarkState(dcd->dcd_Centered, TRUE));
  428.  
  429.  /* Return 1 to indicate that the method is implemented */
  430.  return(1);
  431. }
  432.  
  433. /* Dock class method: TMM_ParseIFF */
  434. #undef  DEBUGFUNCTION
  435. #define DEBUGFUNCTION DockClassParseIFF
  436. static ULONG DockClassParseIFF(Class *cl, Object *obj,
  437.                                struct TMP_ParseIFF *tmppi)
  438. {
  439.  BOOL rc = FALSE;
  440.  
  441.  DOCK_LOG(LOG1(Handle, "0x%08lx", tmppi->tmppi_IFFHandle))
  442.  
  443.  /* Initialize IFF parser */
  444.  if ((PropChunks(tmppi->tmppi_IFFHandle, PropChunkTable, PROPCHUNKS) == 0) &&
  445.      (CollectionChunk(tmppi->tmppi_IFFHandle, ID_TMDO, ID_ENTR) == 0) &&
  446.      (StopOnExit(tmppi->tmppi_IFFHandle, ID_TMDO, ID_FORM) == 0) &&
  447.      (ParseIFF(tmppi->tmppi_IFFHandle, IFFPARSE_SCAN) == IFFERR_EOC)) {
  448.   struct StoredProperty *spname;
  449.  
  450.   DOCK_LOG(LOG0(FORM TMDO chunk parsed OK))
  451.  
  452.   /* Check for mandatory NAME property */
  453.   if (spname = FindProp(tmppi->tmppi_IFFHandle, ID_TMDO, ID_NAME)) {
  454.    struct StoredProperty *spdata;
  455.  
  456.    DOCK_LOG(LOG2(Name, "%s (0x%08lx)", spname->sp_Data, spname->sp_Data))
  457.  
  458.    /* Check for mandatory DATA property */
  459.    if (spdata = FindProp(tmppi->tmppi_IFFHandle, ID_TMDO, ID_DATA)) {
  460.     struct DockClassData *dcd = TYPED_INST_DATA(cl, obj);
  461.     struct DockDATAChunk *ddc = spdata->sp_Data;
  462.  
  463.     DOCK_LOG(LOG5(Data1, "ID 0x%08lx Flags 0x%08lx X %ld Y %ld Cols %ld",
  464.                   ddc->ddc_Standard.sdc_ID, ddc->ddc_Standard.sdc_Flags,
  465.                   ddc->ddc_LeftEdge, ddc->ddc_TopEdge, ddc->ddc_Columns))
  466.     DOCK_LOG(LOG3(Data2, "Font YSize %ld Style 0x%02lx Flags 0x%02lx",
  467.                   ddc->ddc_FontYSize, ddc->ddc_FontStyle, ddc->ddc_FontFlags))
  468.  
  469.     /* Set new name and ID */
  470.     SetAttrs(obj, TMA_Name, spname->sp_Data,
  471.                   TMA_ID,   ddc->ddc_Standard.sdc_ID,
  472.                   TAG_DONE);
  473.  
  474.     /* Copy values from data chunk */
  475.     dcd->dcd_Flags    = ddc->ddc_Standard.sdc_Flags & DATA_DOCKF_MASK;
  476.     dcd->dcd_LeftEdge = ddc->ddc_LeftEdge;
  477.     dcd->dcd_TopEdge  = ddc->ddc_TopEdge;
  478.     dcd->dcd_Columns  = ddc->ddc_Columns;
  479.  
  480.     /* Sanity check */
  481.     if (dcd->dcd_Columns == 0) dcd->dcd_Columns = 1;
  482.  
  483.     /* Get string values */
  484.     dcd->dcd_HotKey    = ReadStringProperty(tmppi->tmppi_IFFHandle, ID_TMDO,
  485.                                             ID_HKEY);
  486.     dcd->dcd_PubScreen = ReadStringProperty(tmppi->tmppi_IFFHandle, ID_TMDO,
  487.                                             ID_PSCR);
  488.  
  489.     /* Retrieve font name */
  490.     if (spdata = FindProp(tmppi->tmppi_IFFHandle, ID_TMDO, ID_FONT)) {
  491.      LONG len = strlen(spdata->sp_Data) - 5;
  492.  
  493.      DOCK_LOG(LOG2(Font, "%s (0x%08lx)", spdata->sp_Data, spdata->sp_Data))
  494.  
  495.      /* Allocate memory for string: name - ".font" + '/' + 5 digits + '\0' */
  496.      if ((len > 0) && (dcd->dcd_Font = GetVector(len + 7))) {
  497.       char  *cp     = dcd->dcd_Font;
  498.       ULONG  height = ddc->ddc_FontYSize;
  499.       ULONG  div    = 10000;
  500.       BOOL   in     = FALSE;
  501.  
  502.       /* Copy name, but strip the trailing ".font" */
  503.       strncpy(cp, spdata->sp_Data, len);
  504.       cp += len;
  505.  
  506.       /* Add separator */
  507.       *cp++ = '/';
  508.  
  509.       /* Sanity check */
  510.       if (height == 0) height = 1;
  511.  
  512.       /* Convert number */
  513.       while (div > 0) {
  514.        char digit = (height / div) + '0';
  515.  
  516.        /* Suppress leading zeros */
  517.        if (in || (digit != '0')) {
  518.  
  519.         /* Copy digit */
  520.         *cp++ = digit;
  521.  
  522.         /* In number */
  523.         in = TRUE;
  524.        }
  525.  
  526.        /* Next digit */
  527.        height %= div;
  528.        div    /= 10;
  529.       }
  530.  
  531.       /* Add string terminator */
  532.       *cp = '\0';
  533.  
  534.       DOCK_LOG(LOG2(Font String, "%s (0x%08lx)", dcd->dcd_Font, dcd->dcd_Font))
  535.      }
  536.     }
  537.  
  538.     /* Read dock entries */
  539.     ReadDockEntries(tmppi->tmppi_IFFHandle, &dcd->dcd_Entries, obj,
  540.                     tmppi->tmppi_Lists);
  541.  
  542.     /* All OK */
  543.     rc = TRUE;
  544.    }
  545.   }
  546.  }
  547.  
  548.  DOCK_LOG(LOG1(Result, "%ld", rc))
  549.  
  550.  return(rc);
  551. }
  552.  
  553. /* Dock class method: TMM_WriteIFF */
  554. #undef  DEBUGFUNCTION
  555. #define DEBUGFUNCTION DockClassWriteIFF
  556. static ULONG DockClassWriteIFF(Class *cl, Object *obj,
  557.                                struct TMP_WriteIFF *tmpwi)
  558. {
  559.  struct DockClassData *dcd  = TYPED_INST_DATA(cl, obj);
  560.  struct DockDATAChunk  ddc;
  561.  char                 *font = NULL;
  562.  BOOL                  rc;
  563.  
  564.  DOCK_LOG(LOG1(IFFHandle, "0x%08lx", tmpwi->tmpwi_IFFHandle))
  565.  
  566.  /* Initialize DATA chunk (use object addresses as IDs) */
  567.  ddc.ddc_Standard.sdc_ID    = (ULONG) obj;
  568.  ddc.ddc_Standard.sdc_Flags = dcd->dcd_Flags;
  569.  ddc.ddc_LeftEdge           = dcd->dcd_LeftEdge;
  570.  ddc.ddc_TopEdge            = dcd->dcd_TopEdge;
  571.  ddc.ddc_Columns            = dcd->dcd_Columns;
  572.  ddc.ddc_FontYSize          = 0;
  573.  ddc.ddc_FontStyle          = 0;
  574.  ddc.ddc_FontFlags          = 0;
  575.  
  576.  /* Analyze font string */
  577.  if (dcd->dcd_Font) {
  578.   char *cp;
  579.  
  580.   /* Search separator and extract font height */
  581.   if ((cp = strchr(dcd->dcd_Font, '/')) &&
  582.       (ddc.ddc_FontYSize = strtol(cp + 1, NULL, 10))) {
  583.    ULONG len = cp - dcd->dcd_Font;
  584.  
  585.    /* Allocate string for font name */
  586.    if (font = GetVector(len + sizeof(".font"))) {
  587.  
  588.     /* Copy font name */
  589.     strncpy(font, dcd->dcd_Font, len);
  590.  
  591.     /* Append ".font" */
  592.     strcpy(font + len, ".font");
  593.  
  594.     DOCK_LOG(LOG2(Font name, "%s (0x%08lx)", font, font))
  595.    }
  596.   }
  597.  }
  598.  
  599.  /* a) Forward message to SuperClass first */
  600.  /* b) Push DATA chunk                     */
  601.  /* c) Push HKEY chunk                     */
  602.  /* d) Push FONT chunk                     */
  603.  /* e) Push PSCR chunk                     */
  604.  /* f) Push ENTR chunks                    */
  605.  rc = DoSuperMethodA(cl, obj, (Msg) tmpwi) &&
  606.       WriteProperty(tmpwi->tmpwi_IFFHandle, ID_DATA, &ddc,
  607.                     sizeof(struct DockDATAChunk))                           &&
  608.       WriteStringProperty(tmpwi->tmpwi_IFFHandle, ID_HKEY, dcd->dcd_HotKey) &&
  609.       WriteStringProperty(tmpwi->tmpwi_IFFHandle, ID_FONT, font)            &&
  610.       ((dcd->dcd_Flags & DATA_DOCKF_FRONTMOST) ||
  611.        WriteStringProperty(tmpwi->tmpwi_IFFHandle, ID_PSCR,
  612.                            dcd->dcd_PubScreen))                             &&
  613.        WriteDockEntries(tmpwi->tmpwi_IFFHandle, &dcd->dcd_Entries);
  614.  
  615.  /* Free font string */
  616.  if (font) FreeVector(font);
  617.  
  618.  DOCK_LOG(LOG1(Result, "%ld", rc))
  619.  
  620.  return(rc);
  621. }
  622.  
  623. /* Dock class method: TMM_WBArg */
  624. #undef  DEBUGFUNCTION
  625. #define DEBUGFUNCTION DockClassWBArg
  626. static ULONG DockClassWBArg(Class *cl, Object *obj, struct TMP_WBArg *tmpwa)
  627. {
  628.  struct DockClassData *dcd  = TYPED_INST_DATA(cl, obj);
  629.  char                 *name = tmpwa->tmpwa_Argument->wa_Name;
  630.  ULONG                 rc   = 0;
  631.  
  632.  DOCK_LOG(LOG2(Name, "%s (0x%08lx)", name, name))
  633.  
  634.  /* Edit active and icon name valid? */
  635.  if (dcd->dcd_Active && name && (*name != '\0')) {
  636.  
  637.   DOCK_LOG(LOG0(Edit active))
  638.  
  639.   /* Yes, forward message to EntryList */
  640.   rc = DoMethodA(dcd->dcd_EntryList, (Msg) tmpwa);
  641.  }
  642.  
  643.  DOCK_LOG(LOG1(Result, "0x%08lx", rc))
  644.  
  645.  return(rc);
  646. }
  647.  
  648. /* Dock class method: TMM_DoubleClicked */
  649. #undef  DEBUGFUNCTION
  650. #define DEBUGFUNCTION DockClassDoubleClicked
  651. static ULONG DockClassDoubleClicked(Class *cl, Object *obj)
  652. {
  653.  struct DockClassData *dcd    = TYPED_INST_DATA(cl, obj);
  654.  ULONG                 column;
  655.  
  656.  DOCK_LOG(LOG0(Entry))
  657.  
  658.  /* Get column from list view */
  659.  GetAttr(MUIA_Listview_ClickColumn, dcd->dcd_ListView, &column);
  660.  
  661.  DOCK_LOG(LOG1(Column, "%ld", column))
  662.  
  663.  /* Call column method on entry list */
  664.  DoMethod(dcd->dcd_EntryList, TMM_Column, column);
  665.  
  666.  /* Return 1 to indicate that the method is implemented */
  667.  return(1);
  668. }
  669.  
  670. /* Dock class method dispatcher */
  671. #undef  DEBUGFUNCTION
  672. #define DEBUGFUNCTION DockClassDispatcher
  673. __geta4 static ULONG DockClassDispatcher(__a0 Class *cl, __a2 Object *obj,
  674.                                          __a1 Msg msg)
  675. {
  676.  ULONG rc;
  677.  
  678.  DOCK_LOG(LOG3(Arguments, "Class 0x%08lx Object 0x%08lx Msg 0x%08lx",
  679.                cl, obj, msg))
  680.  
  681.  switch(msg->MethodID) {
  682.   /* BOOPSI methods */
  683.   case OM_NEW:
  684.    rc = DockClassNew(cl, obj, (struct opSet *) msg);
  685.    break;
  686.  
  687.   case OM_DISPOSE:
  688.    rc = DockClassDispose(cl, obj, msg);
  689.    break;
  690.  
  691.   /* TM methods */
  692.   case TMM_Finish:
  693.    rc = DockClassFinish(cl, obj, (struct TMP_Finish *) msg);
  694.    break;
  695.  
  696.   case TMM_Notify:
  697.    rc = DockClassNotify(cl, obj, (struct TMP_Notify *) msg);
  698.    break;
  699.  
  700.   case TMM_Edit:
  701.    rc = DockClassEdit(cl, obj, (struct TMP_Edit *) msg);
  702.    break;
  703.  
  704.   case TMM_Change:
  705.    rc = DockClassChange(cl, obj);
  706.    break;
  707.  
  708.   case TMM_ParseIFF:
  709.    rc = DockClassParseIFF(cl, obj, (struct TMP_ParseIFF *) msg);
  710.    break;
  711.  
  712.   case TMM_WriteIFF:
  713.    rc = DockClassWriteIFF(cl, obj, (struct TMP_WriteIFF *) msg);
  714.    break;
  715.  
  716.   case TMM_WBArg:
  717.    rc = DockClassWBArg(cl, obj, (struct TMP_WBArg *) msg);
  718.    break;
  719.  
  720.   case TMM_DoubleClicked:
  721.    rc = DockClassDoubleClicked(cl, obj);
  722.    break;
  723.  
  724.   /* Unknown method -> delegate to SuperClass */
  725.   default:
  726.    rc = DoSuperMethodA(cl, obj, msg);
  727.    break;
  728.  }
  729.  
  730.  return(rc);
  731. }
  732.  
  733. /* Create Dock class */
  734. #undef  DEBUGFUNCTION
  735. #define DEBUGFUNCTION CreateDockClass
  736. struct MUI_CustomClass *CreateDockClass(void)
  737. {
  738.  struct MUI_CustomClass *rc;
  739.  
  740.  /* Create class */
  741.  if (rc = MUI_CreateCustomClass(NULL, NULL, BaseClass,
  742.                                 sizeof(struct DockClassData),
  743.                                 DockClassDispatcher)) {
  744.  
  745.   /* Localize strings */
  746.   TextTitle        = TranslateString(LOCALE_TEXT_DOCK_TITLE_STR,
  747.                                      LOCALE_TEXT_DOCK_TITLE);
  748.   HelpHotKey       = TranslateString(LOCALE_HELP_DOCK_HOTKEY_STR,
  749.                                      LOCALE_HELP_DOCK_HOTKEY);
  750.   HelpPublicScreen = TranslateString(LOCALE_HELP_DOCK_PUBLIC_SCREEN_STR,
  751.                                      LOCALE_HELP_DOCK_PUBLIC_SCREEN);
  752.   HelpPosition     = TranslateString(LOCALE_HELP_DOCK_POSITION_STR,
  753.                                      LOCALE_HELP_DOCK_POSITION);
  754.   TextFont         = TranslateString(LOCALE_TEXT_DOCK_FONT_STR,
  755.                                      LOCALE_TEXT_DOCK_FONT);
  756.   HelpFont         = TranslateString(LOCALE_HELP_DOCK_FONT_STR,
  757.                                      LOCALE_HELP_DOCK_FONT);
  758.   TextColumns      = TranslateString(LOCALE_TEXT_DOCK_COLUMNS_STR,
  759.                                      LOCALE_TEXT_DOCK_COLUMNS);
  760.   HelpColumns      = TranslateString(LOCALE_HELP_DOCK_COLUMNS_STR,
  761.                                      LOCALE_HELP_DOCK_COLUMNS);
  762.   TextActivated    = TranslateString(LOCALE_TEXT_DOCK_ACTIVATED_STR,
  763.                                      LOCALE_TEXT_DOCK_ACTIVATED);
  764.   HelpActivated    = TranslateString(LOCALE_HELP_DOCK_ACTIVATED_STR,
  765.                                      LOCALE_HELP_DOCK_ACTIVATED);
  766.   TextBackdrop     = TranslateString(LOCALE_TEXT_DOCK_BACKDROP_STR,
  767.                                      LOCALE_TEXT_DOCK_BACKDROP);
  768.   HelpBackdrop     = TranslateString(LOCALE_HELP_DOCK_BACKDROP_STR,
  769.                                      LOCALE_HELP_DOCK_BACKDROP);
  770.   TextBorder       = TranslateString(LOCALE_TEXT_DOCK_BORDER_STR,
  771.                                      LOCALE_TEXT_DOCK_BORDER);
  772.   HelpBorder       = TranslateString(LOCALE_HELP_DOCK_BORDER_STR,
  773.                                      LOCALE_HELP_DOCK_BORDER);
  774.   TextCentered     = TranslateString(LOCALE_TEXT_DOCK_CENTERED_STR,
  775.                                      LOCALE_TEXT_DOCK_CENTERED);
  776.   HelpCentered     = TranslateString(LOCALE_HELP_DOCK_CENTERED_STR,
  777.                                      LOCALE_HELP_DOCK_CENTERED);
  778.   TextFrontmost    = TranslateString(LOCALE_TEXT_DOCK_FRONTMOST_STR,
  779.                                      LOCALE_TEXT_DOCK_FRONTMOST);
  780.   HelpFrontmost    = TranslateString(LOCALE_HELP_DOCK_FRONTMOST_STR,
  781.                                      LOCALE_HELP_DOCK_FRONTMOST);
  782.   TextImages       = TranslateString(LOCALE_TEXT_DOCK_IMAGES_STR,
  783.                                      LOCALE_TEXT_DOCK_IMAGES);
  784.   HelpImages       = TranslateString(LOCALE_HELP_DOCK_IMAGES_STR,
  785.                                      LOCALE_HELP_DOCK_IMAGES);
  786.   TextMenu         = TranslateString(LOCALE_TEXT_DOCK_MENU_STR,
  787.                                      LOCALE_TEXT_DOCK_MENU);
  788.   HelpMenu         = TranslateString(LOCALE_HELP_DOCK_MENU_STR,
  789.                                      LOCALE_HELP_DOCK_MENU);
  790.   TextPopup        = TranslateString(LOCALE_TEXT_DOCK_POPUP_STR,
  791.                                      LOCALE_TEXT_DOCK_POPUP);
  792.   HelpPopup        = TranslateString(LOCALE_HELP_DOCK_POPUP_STR,
  793.                                      LOCALE_HELP_DOCK_POPUP);
  794.   TextSticky       = TranslateString(LOCALE_TEXT_DOCK_STICKY_STR,
  795.                                      LOCALE_TEXT_DOCK_STICKY);
  796.   HelpSticky       = TranslateString(LOCALE_HELP_DOCK_STICKY_STR,
  797.                                      LOCALE_HELP_DOCK_STICKY);
  798.   TextText         = TranslateString(LOCALE_TEXT_DOCK_TEXT_STR,
  799.                                      LOCALE_TEXT_DOCK_TEXT);
  800.   HelpText         = TranslateString(LOCALE_HELP_DOCK_TEXT_STR,
  801.                                      LOCALE_HELP_DOCK_TEXT);
  802.   TextEntries      = TranslateString(LOCALE_TEXT_DOCK_ENTRIES_STR,
  803.                                      LOCALE_TEXT_DOCK_ENTRIES);
  804.   HelpEntries      = TranslateString(LOCALE_HELP_DOCK_ENTRIES_STR,
  805.                                      LOCALE_HELP_DOCK_ENTRIES);
  806.   TextSelectFont   = TranslateString(LOCALE_TEXT_DOCK_SELECT_FONT_STR,
  807.                                      LOCALE_TEXT_DOCK_SELECT_FONT);
  808.  }
  809.  
  810.  DOCK_LOG(LOG1(Result, "0x%08lx", rc))
  811.  
  812.  return(rc);
  813. }
  814.